#pragma once

#include "kernel/dtos/map_display_dto.h"
#include "application/pathfinding/pathfinding_graph.h"
#include "kernel/interfaces/Result.h"
#include "kernel/domain/map_types.h"
#include "kernel/interfaces/ILogger.h"
#include "kernel/domain/map_extend_types.h"
#include "infrastructure/services/common_service.h"
#include "application/map/area/area_manager.h"
#include "application/map/charge/charge_manager.h"
#include "application/map/park/park_manager.h"
#include "application/map/lift/lift_manager.h"
#include "application/map/lift/hk_lift.h"
#include "application/map/caller/caller_manager.h"
#include "application/map/auto_door/auto_door_manager.h"
#include "application/map/third_area/third_area_manager.h"
#include <QString>
#include <QObject>
#include <QVector>
#include <QHash>
#include <QColor>
#include <QSet>
#include <memory>

// Forward declarations to avoid including infrastructure headers
namespace infrastructure {
	class MapService;
    class MapExtendLoader;
}

namespace infrastructure {
	namespace services {
		class CommonService;
	}
}

namespace kernel {
	class Map;
}

namespace application {

	/**
	 * @brief 楼层地图信息结构
	 */
	struct FloorMapInfo {
		int floor;                                          // 楼层�?
		QString userName;                                   // 地图用户名称
		QString filePath;                                   // 地图文件路径
		std::shared_ptr<kernel::Map> mapData;               // 地图数据（内存中的地图对象）
		bool isLoaded = false;                              // 是否已加�?

		// 子系统管理器
		std::shared_ptr<area::AreaManager> areaManager;
		std::shared_ptr<charge::ChargeManager> chargeManager;
		std::shared_ptr<park::ParkManager> parkManager;
		std::shared_ptr<lift::LiftManager> liftManager;
		std::shared_ptr<caller::CallerManager> callerManager;
		std::shared_ptr<auto_door::AutoDoorManager> autoDoorManager;
		std::shared_ptr<third_area::ThirdAreaManager> thirdAreaManager;
	};

	/**
	 * MapApplicationService serves as a facade between the presentation layer
	 * and the infrastructure layer, maintaining Clean Architecture principles.
	 *
	 * This service provides a stable API for presentation layer components
	 * while delegating actual map operations to the infrastructure layer.
	 *
	 * Supports multi-floor map management with hash-based lookup.
	 */
	class MapApplicationService : public QObject {
		Q_OBJECT

	public:
		explicit MapApplicationService(std::shared_ptr<infrastructure::MapService> mapService,
			std::shared_ptr<infrastructure::services::CommonService> commonService = std::shared_ptr<infrastructure::services::CommonService>(),
            std::shared_ptr<infrastructure::MapExtendLoader> extendLoader = std::shared_ptr<infrastructure::MapExtendLoader>(),
			QObject* parent = nullptr);
		~MapApplicationService() = default;

		// Map loading operations
		kernel::Result<void> loadMapFromFile(const QString& filePath);
		kernel::Result<void> loadDefaultMap();
		kernel::Result<void> loadAllMapsFromConfig();  // 新增: 加载所有配置的地图
		void refreshMapData();

		// Multi-floor map operations
		kernel::Result<void> switchToFloor(int floor);  // 新增: 切换到指定楼�?
		std::shared_ptr<infrastructure::MapService> getMapByFloor(int floor) const;  // 新增: 按楼层获取地�?
		std::shared_ptr<infrastructure::MapService> getMapByName(const QString& mapName) const;  // 新增: 按名称获取地�?
		int getCurrentFloor() const;  // 新增: 获取当前楼层
		QVector<int> getLoadedFloors() const;  // 新增: 获取已加载的楼层列表

		// Subsystem access
		std::shared_ptr<area::AreaManager> getAreaManager(int floor) const;
		std::shared_ptr<charge::ChargeManager> getChargeManager(int floor) const;
		std::shared_ptr<park::ParkManager> getParkManager(int floor) const;
	std::shared_ptr<lift::LiftManager> getLiftManager() const;
	std::shared_ptr<caller::CallerManager> getCallerManager(int floor) const;
	std::shared_ptr<auto_door::AutoDoorManager> getAutoDoorManager(int floor) const;
	std::shared_ptr<third_area::ThirdAreaManager> getThirdAreaManager(int floor) const;

		// Data access for UI layer
		kernel::MapDisplayDto getMapForDisplay() const;
		PathfindingGraphPtr getPathfindingGraph(int floor) const;

		// Map information queries
		bool isMapLoaded() const;
		QString getCurrentMapName() const;
		// Map name lookup by floor
		QString getMapNameForFloor(int floor) const;
		// Floor lookup by map name; returns -1 if not found
    int getFloorForMapName(const QString& mapName) const;
    kernel::Position getMapBounds() const;
		double getMapResolution() const;
		// Block area helpers
		QString getBlockAreaForStation(int floor, const QString& stationName) const;
		bool isBlockArea(int floor, const QString& areaId) const;

		// Station operations
        QString getStationName(int stationNumber) const;
        QVector<QString> getAllStationNames(int floor) const;
        kernel::Position getStationPosition(const QString& stationName, int floor) const;
        QString getAreaIdForStation(int floor, const QString& stationName) const;
		
        // Current position operations
        void updateCurrentPosition(double x, double y, double angle);
        kernel::Position getCurrentPosition() const;
		double getCurrentAngle() const;

	signals:
		void mapLoadFinished();
		void mapLoadFailed(const QString& error);
		void floorMapLoaded(int floor);  // 新增: 单个楼层地图加载完成信号
		void currentPositionChanged();
		void floorChanged(int floor);  // 新增: 楼层切换信号

	private slots:
		void onMapServiceLoadFinished();
		void onMapServiceLoadFailed(const QString& error);

	private:
		std::shared_ptr<infrastructure::MapService> mapService_;  // 无状态的文件读取服务
	std::shared_ptr<kernel::ILogger> m_logger;
	std::shared_ptr<kernel::IConfiguration> m_config;
	std::shared_ptr<infrastructure::MapExtendLoader> m_extendLoader;

		QString m_esmapConfigIdentifier;
		// Multi-floor map management
		QHash<int, FloorMapInfo> m_floorMaps;       // 楼层�?-> 地图信息
		QHash<QString, int> m_mapNameToFloor;       // 地图名称 -> 楼层�?
		int m_currentFloor = -1;                    // 当前楼层
		QString m_itemName;                         // 项目名称

		// Current position tracking
		kernel::Position m_currentPosition;
		double m_currentAngle{ 0.0 };
	std::shared_ptr<lift::LiftManager> m_sharedLiftManager;
	std::shared_ptr<caller::CallerManager> m_sharedCallerManager;
	std::shared_ptr<auto_door::AutoDoorManager> m_sharedAutoDoorManager;
	std::shared_ptr<third_area::ThirdAreaManager> m_sharedThirdAreaManager;
	kernel::MapExtendedData m_cachedExtendData;
	bool m_extendConfigLoaded{false};
	QSet<int> m_registeredLiftNums;
	QSet<int> m_registeredCallerNums;
	QSet<QString> m_registeredThirdAreaIds;
	QHash<int, QSet<QString>> m_blockAreaIds;
	bool m_thirdAreaServerStarted{false};

		void connectToMapService();
		kernel::Result<void> loadFloorMap(const FloorMapInfo& mapInfo);  // 加载单个楼层地图
		void initializeSubsystems(FloorMapInfo& mapInfo);  // 初始化子系统
		void initializeThirdAreaManager();

		// 辅助方法：获取当前楼层的 Map 对象
		std::shared_ptr<kernel::Map> getCurrentMap() const;
		std::shared_ptr<kernel::Map> getMapForFloor(int floor) const;
		bool ensureExtendConfigLoaded();
		void populateAreaManager(FloorMapInfo& mapInfo);
		void loadExtendedSubsystemData(FloorMapInfo& mapInfo);

		// 扩展资源注入辅助方法
		void injectLiftData(FloorMapInfo& mapInfo, const QString& mapName);
		void injectCallerData(FloorMapInfo& mapInfo);
		void injectThirdAreaData(FloorMapInfo& mapInfo);
		void injectChargeStationData(FloorMapInfo& mapInfo, const QString& mapName);
		void injectParkStationData(FloorMapInfo& mapInfo, const QString& mapName);
		void injectAutoDoorData(FloorMapInfo& mapInfo, const QString& mapName);
        std::shared_ptr<area::Area> findAreaForStation(const FloorMapInfo& mapInfo, const QString& stationName) const;
        std::shared_ptr<area::Area> findAreaForStation(int floor, const QString& stationName) const;
        int updateLiftFloorAreasForMap(const kernel::LiftConfig& liftConfig,
                                       const FloorMapInfo& mapInfo,
                                       const std::shared_ptr<lift::BaseLift>& liftObj);
	};

} // namespace application
